package com.codeworker.app.ui.bill;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.IdRes;
import androidx.annotation.RequiresApi;

import com.codeworker.app.MainActivity;
import com.codeworker.app.R;
import com.codeworker.app.data.common.enums.BillTypeEnum;
import com.codeworker.app.data.common.enums.PayTypeEnum;
import com.codeworker.app.data.entity.Bill;
import com.codeworker.app.data.repository.BillRepository;
import com.codeworker.app.data.repository.PropertyRepository;
import com.codeworker.app.databinding.ActivityBillFormBinding;
import com.codeworker.app.ui.wrapper.MyBaseActivity;
import com.codeworker.app.ui.wrapper.MyPopupWindow;
import com.codeworker.app.ui.wrapper.MyPopupWindowAdapter;
import com.codeworker.app.ui.wrapper.MyTextWatcher;
import com.codeworker.app.utils.MoneyUtil;
import com.codeworker.app.utils.ReflectUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class AddBillActivity extends MyBaseActivity {
    private List<MyPopupWindowAdapter.PopupWindowViewHolderInDB> popupWindowItems;
    private PropertyRepository propertyRepository;
    private Button btn;
    private TextView tvPayType;
    private TextView tvBillType;
    private TextView tvPayTypeId;
    private TextView tvBillTypeId;
    private TextView tvBillBelong;
    private TextView tvBillBelongId;
    private EditText etRemark;
    private EditText etBillValue;
    private View view;

    @RequiresApi(api = Build.VERSION_CODES.Q)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityBillFormBinding binding = ActivityBillFormBinding.inflate(getLayoutInflater());
        view = binding.getRoot();
        setContentView(view);
        setToolbar(this);
        initView(view);

        propertyRepository = new PropertyRepository(this.getApplication());
        if (!propertyRepository.getProperties().isEmpty()) {
            tvBillBelong.setText(propertyRepository.getProperties().get(0).getName());
            tvBillBelongId.setText(String.valueOf(propertyRepository.getProperties().get(0).getId()));
        }

        etBillValue.addTextChangedListener(new MyTextWatcher());
        tvPayType.setOnClickListener(v -> {
            popupWindowEvent(v, R.id.tv_pay_type, tvPayType, tvPayTypeId, false);
        });
        tvBillType.setOnClickListener(v -> {
            popupWindowEvent(v, R.id.tv_bill_type, tvBillType, tvBillTypeId, false);
        });
        tvBillBelong.setOnClickListener(v -> {
            popupWindowEvent(v, R.id.tv_bill_belong, tvBillBelong, tvBillBelongId, true);
        });
        btn.setOnClickListener(v -> btnClickEvent(v, etBillValue, tvPayTypeId, tvBillTypeId, tvBillBelongId));
    }

    /**
     * 视图初始化
     */
    private void initView(View view) {
        tvPayType = view.findViewById(R.id.tv_pay_type);
        tvPayTypeId = view.findViewById(R.id.tv_pay_type_id);
        tvBillType = view.findViewById(R.id.tv_bill_type);
        tvBillTypeId = view.findViewById(R.id.tv_bill_type_id);
        tvBillBelong = view.findViewById(R.id.tv_bill_belong);
        tvBillBelongId = view.findViewById(R.id.tv_bill_belong_id);
        btn = view.findViewById(R.id.btn_handle_bill);
        etRemark = view.findViewById(R.id.et_bill_remark);
        etBillValue = view.findViewById(R.id.et_bill_value);
    }

    /**
     * Button监听事件
     */
    private void btnClickEvent(View v, EditText etBillValue,
                               TextView tvPayTypeId, TextView tvBillTypeId, TextView tvBillBelongId) {
        if (TextUtils.isEmpty(etBillValue.getText())) {
            Toast.makeText(v.getContext(), R.string.toast_must_not_null, Toast.LENGTH_SHORT).show();
            return;
        }
        int payType = Integer.parseInt(tvPayTypeId.getText().toString());
        int billType = Integer.parseInt(tvBillTypeId.getText().toString());
        int billBelong = Integer.parseInt(tvBillBelongId.getText().toString());
        int billValue = (int) (MoneyUtil.mul(Double.parseDouble(etBillValue.getText().toString()), 100.0));
        String remark = etRemark.getText().toString();
        Bill bill = new Bill(payType, billBelong, billValue, billType, remark);
        BillRepository billRepository = new BillRepository(getApplication());
        billRepository.insert(bill);
        Intent intent = new Intent(v.getContext(), MainActivity.class);
        startActivity(intent);
    }

    /**
     * 弹窗事件
     */
    @RequiresApi(api = Build.VERSION_CODES.N)
    private void popupWindowEvent(View v, @IdRes int viewId, TextView tv, TextView tvId, boolean needFixedHeight) {
        // 如果存在软键盘打开，关闭软键盘
        InputMethodManager inputMethodManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
        @SuppressLint("InflateParams") View popUpView
                = LayoutInflater.from(v.getContext()).inflate(R.layout.layout_common_popup, null);
        // 设置适配器的数据项
        ListView listView = popUpView.findViewById(R.id.lv_common_popup);
        initListView(v, viewId, listView);

        // 设置弹窗
        MyPopupWindow myPopupWindow = new MyPopupWindow(popUpView, this,
                needFixedHeight && popupWindowItems.size() > MyPopupWindow.MAX_POPUP_WINDOW_ITEMS_SIZE);

        // 弹出创建显示在按钮下面
        myPopupWindow.showAtLocation(v, Gravity.BOTTOM, 0, 0);
        // 弹窗事件监听
        listView.setOnItemClickListener((parent, view, position, id) -> listViewClickEvent(tv, tvId, position, myPopupWindow));
    }

    /**
     * 初始化弹窗数据
     */
    private <T> void initPopupWindowItems(List<T> data, String itemName, String idName) {
        for(T o : data) {
            popupWindowItems.add(
                    new MyPopupWindowAdapter.PopupWindowViewHolderInDB(
                            (String) ReflectUtil.getValueByGetter(itemName, o),
                            (Integer) ReflectUtil.getValueByGetter(idName, o)
                    )
            );
        }
    }

    /**
     * 设置弹窗适配器的数据项
     */
    @SuppressLint("NonConstantResourceId")
    private void initListView(View v, @IdRes int viewId, ListView listView ) {
        popupWindowItems = new ArrayList<>();
        switch (viewId) {
            case R.id.tv_pay_type:
                initPopupWindowItems(Arrays.asList(PayTypeEnum.values()), "payTypeDesc", "payTypeInDB");
                break;
            case R.id.tv_bill_type:
                initPopupWindowItems(BillTypeEnum.getBillTypeValueByPayType(PayTypeEnum.getPayTypeInDB(tvPayType.getText().toString())),
                        "billTypeDesc", "billTypeInDB");
                break;
            case R.id.tv_bill_belong:
                initPopupWindowItems(propertyRepository.getProperties(), "name", "id");
                break;
            default: throw new RuntimeException();
        }
        // 初始化适配器
        MyPopupWindowAdapter adapter = new MyPopupWindowAdapter(v.getContext(), popupWindowItems);
        listView.setAdapter(adapter);
    }

    private void listViewClickEvent(TextView tv, TextView tvId, int position, MyPopupWindow myPopupWindow) {
        tv.setText(popupWindowItems.get(position).getItem());
        tvId.setText(String.valueOf(popupWindowItems.get(position).getId()));
        // 关闭弹出框
        myPopupWindow.dismiss();
        // 如果弹窗是收支类型，则相关的记账类型随之变动：188-193是双if，不能调整为三元表达式
        if (PayTypeEnum.INCOME.getPayTypeDesc().equals(tv.getText().toString())) {
            tvBillType.setText(BillTypeEnum.IN_SALARY.getBillTypeDesc());
        }
        if (PayTypeEnum.EXPEND.getPayTypeDesc().equals(tv.getText().toString())) {
            tvBillType.setText(BillTypeEnum.EX_EAT.getBillTypeDesc());
        }
    }

}
